from .ir import Component, ConfigIR
from .registry import REGISTRY
from .resolver import AbstractResolver
from .resource_loader import AbstractResourceLoader
from ..estimator.container import ComponentContainer


class ComponentContainerBuilder:

    def __init__(self, resource_loader: AbstractResourceLoader, resolver: AbstractResolver):
        self.loader = resource_loader
        self.resolver = resolver

    def build(self, configfile: str) -> ComponentContainer:
        config_ir = self.loader.load(configfile)
        container = ComponentContainer()

        for component_name in ConfigIR.components:
            config = getattr(config_ir, component_name)
            if config is not None:
                component = self._build_component(config, container)
                setattr(container, component_name, component)

        return container

    def _build_component(self, component, container) -> object:
        if isinstance(component, Component):
            for key, value in component.kwargs.items():
                component.set(key, self._build_component(value, container))

            cls_name = component.type
            cls = REGISTRY.get(cls_name)
            return cls(**component.kwargs)
        elif isinstance(component, (tuple, list)):
            components = []
            for item in component:
                components.append(self._build_component(item, container))

            return components
        else:
            return self.resolver.resolve(component, container)
